home *** CD-ROM | disk | FTP | other *** search
- program xbox1;
- {
- Texture-mapped box rotating around x-axis
- - by Bjarke Viksφe
- apr 1994
-
- THIS PROGRAM WAS CODED BY BJARKE VIKS0E.
- YOU ARE FREE TO DO WHATEVER YOU WANT WITH THIS PIECE OF CODE.
- E-MAIL ME AT: dat92230@rix02.lyngbyes.dk IN 1994 FOR CHAT AND CODE.
- }
-
- {$A+,B-,G+,E+,I+,N-,X+}
-
- uses
- DEMOINIT, ILBM256;
-
- (*{$DEFINE DEBUG}*)
-
- const
- ANTAL_COORDS = 4;
- LOGO_HEIGHT = 63;
- SCR_POS = WIDTH*70;
-
- type
- coordbuffer = array[1..4*3] of integer;
- midarray = array[1..320] of word;
-
- var
- v1 : word;
- sin1,cos1 : integer;
- sinustabel : array [0..639] of integer;
-
- xkoord,ykoord,zkoord : integer;
- coords : coordbuffer;
- cbuffer : coordbuffer;
-
- buffer : pScreen;
- logo : pScreen;
- midtabeller : array[1..160] of ^midarray;
-
- midxtabel : array[0..200] of word;
- midytabel : array[0..200] of word;
- ytabel320 : array[0..200] of word;
-
- const
- display1 : word = $0000;
- display2 : word = $4000;
- display3 : word = $8000;
-
-
- (*------------------------------------------------*)
-
- procedure CalcInBetweens;
- var
- i,j : integer;
- x1,xadd : real;
- begin
- for i:=161 to 320 do begin
- GetMem(midtabeller[i-160],SizeOf(word)*i);
- x1:=0.0;
- xadd:=(320.0)/(i);
- for j:=1 to i do begin
- midtabeller[i-160]^[j]:=round(x1);
- x1:=x1+xadd;
- end;
- end;
- end;
-
-
- procedure SetupSinus;
- var
- i : integer;
- v, vadd : real;
- begin
- v:=0.0;
- vadd:=(2.0*pi/512.0);
- for i:=0 to 639 do begin
- sinustabel[i]:=round(sin(v)*32767);
- v:=v+vadd;
- end;
- end;
-
- procedure InitCoords;
- const
- X = 440;
- Y = 60;
- Z = 60;
- begin
- coords[1]:=-X; coords[2]:=Y; coords[3]:=Z;
- coords[4]:=-X; coords[5]:=Y; coords[6]:=-Z;
- coords[7]:=-X; coords[8]:=-Y; coords[9]:=-Z;
- coords[10]:=-X; coords[11]:=-Y; coords[12]:=Z;
- end;
-
- procedure InitDemo;
- var
- i : integer;
- begin
- ClearWholeScreen;
- SetupSinus;
- InitCoords;
- New(buffer);
- fillchar(buffer^,SizeOf(buffer^),0);
- New(logo);
- LoadPix(logo,'PARASIT2.LBM');
- SetCMAP;
- CalcInBetweens;
- for i:=0 to 200 do ytabel320[i]:=i*320;
- v1:=0;
- end;
-
- procedure UninitDemo;
- var
- i : integer;
- begin
- Dispose(logo);
- Dispose(buffer);
- for i:=161 to 320 do FreeMem(midtabeller[i-160],SizeOf(word)*i);
- end;
-
-
- (*------------------------------------------------*)
-
- procedure SwapDisplay;
- var
- temp : word;
- begin
- temp:=display3;
- display3:=display2;
- display2:=display1;
- display1:=temp;
- SetAddress(Ptr(SEGA000,display2));
- end;
-
-
- procedure CalcVinkel;
- begin
- sin1:=sinustabel[v1];
- cos1:=sinustabel[v1+128];
- v1:=(v1+3) AND 511;
- end;
-
- procedure RotateAllCoords; assembler;
- var
- n : integer;
- asm
- mov ax,ds
- mov es,ax
- lea si,coords
- lea di,cbuffer
- mov n,ANTAL_COORDS
- cld
- @loop:
- lodsw
- mov xkoord,ax
- lodsw
- mov ykoord,ax
- lodsw
- mov zkoord,ax
-
- mov ax,ykoord {rotate around Y-axis}
- push ax
- imul Cos1
- add ax,ax
- adc dx,dx
- mov bx,dx
- mov ax,zkoord
- imul Sin1
- add ax,ax
- adc dx,dx
- sub bx,dx
- mov ykoord,bx
- pop ax
- imul Sin1
- add ax,ax
- adc dx,dx
- mov bx,dx
- mov ax,zkoord
- imul Cos1
- add ax,ax
- adc dx,dx
- add bx,dx
- mov zkoord,bx
-
- add bx,800
- and bx,bx
- jnz @zero
- mov bl,1
- @zero:
-
- mov ax,xkoord
- cwd
- mov dl,ah
- mov ah,al
- xor al,al
- idiv bx
- stosw
-
- mov ax,ykoord
- cwd
- mov dl,ah
- mov ah,al
- xor al,al
- idiv bx
- add ax,28
- stosw
-
- dec n
- jne @loop
- end;
-
-
- (*------------------------------------------------*)
-
- procedure CalcSlope(a1,a2,n : integer; tabel : pointer);
- var
- dela : longint;
- begin
- if (n<1) then exit;
- dela := (a2-a1)*($10000 DIV (n));
- asm
- les di,tabel
- mov si,n
- mov ax,a1
- xor dx,dx
- mov cx,WORD PTR dela
- mov bx,WORD PTR dela+2
- cld
- @loop1:
- add dx,cx
- adc ax,bx
- stosw
- dec si
- jnz @loop1
- end;
- end;
-
-
- (*------------------------------------------------*)
-
- procedure DrawScreen;
- procedure CopyBuffer(yoffset : word); assembler;
- asm
- push ds
- mov es,SEGA000
- mov di,display1
- add di,SCR_POS
- lds si,buffer
- add si,yoffset
- mov cx,(WIDTH*60)/4
- cld
- {rep movsd} DB $F3,$66,$A5
- pop ds
- end;
- begin
- SetBitplanes(4);
- CopyBuffer($0000);
- SetBitplanes(8);
- CopyBuffer($4000);
- SetBitplanes(1);
- CopyBuffer($8000);
- SetBitplanes(2);
- CopyBuffer($C000);
- end;
-
- procedure ClearTopBottom; assembler;
- const
- toplines = 8;
- bottomlines = 8;
- downoffset = 48*WIDTH;
- asm
- cld
- {xor eax,eax} DB $66,$33,$C0
- les di,buffer
- mov dx,(WIDTH*TOPLINES)/4
- mov cx,dx
- {rep stosd} DB $F3,$66,$AB
- les di,buffer
- add di,$4000
- mov cx,dx
- {rep stosd} DB $F3,$66,$AB
- les di,buffer
- add di,$8000
- mov cx,dx
- {rep stosd} DB $F3,$66,$AB
- les di,buffer
- add di,$C000
- mov cx,dx
- {rep stosd} DB $F3,$66,$AB
-
- les di,buffer
- mov dx,(WIDTH*BOTTOMLINES)/4
- add di,downoffset
- mov cx,dx
- {rep stosd} DB $F3,$66,$AB
- les di,buffer
- add di,downoffset+$4000
- mov cx,dx
- {rep stosd} DB $F3,$66,$AB
- les di,buffer
- add di,downoffset+$8000
- mov cx,dx
- {rep stosd} DB $F3,$66,$AB
- les di,buffer
- add di,downoffset+$C000
- mov cx,dx
- {rep stosd} DB $F3,$66,$AB
- end;
-
-
- (*------------------------------------------------*)
-
- procedure PaintLine(x : integer; midtabel : pointer;
- yoffset,logooffset : word); assembler;
- const
- offadd : array[0..3] of word = ($8000,$C000,$0000,$4000);
- asm
- push ds
- push bp
- les di,buffer
- add di,yoffset
- mov bx,x
- add bx,160
- and bx,3
- shl bx,1
- add di,[OFFSET offadd+bx]
- mov ax,x
- add ax,160
- sar ax,2
- add di,ax
-
- mov ax,WORD PTR logo+2
- {mov fs,ax} DB $8E,$E0
- mov dx,WORD PTR logo
- add dx,logooffset
- lds si,midtabel
- mov cx,x
- neg cx
- shl cx,1
- cld
- mov bp,$4000
- @loop:
- lodsw
- mov bx,dx
- add bx,ax
- DB FS; mov al,[bx]
- mov [es:di],al
- add di,bp
- jno @nooverflow
- inc di
- @nooverflow:
- loop @loop
- pop bp
- pop ds
- end;
-
-
- (*------------------------------------------------*)
-
- procedure DrawFace(x2,y2,x1,y1 : integer);
- var
- i : integer;
- x,yoffset,logooffset : word;
- height : integer;
- begin
- height:=y2-y1;
- if (height<=1) then exit;
- if y1<0 then halt;
- CalcSlope(x1,x2,height,@midxtabel);
- CalcSlope(0,LOGO_HEIGHT,height,@midytabel);
-
- {mulu 320 to all values in "midytabel"}
- asm
- mov ax,ds
- mov es,ax
- lea di,midytabel
- lea si,ytabel320
- mov cx,height
- cld
- @loop:
- mov bx,[di]
- shl bx,1
- mov ax,[si+bx]
- stosw
- loop @loop
- end;
-
- logooffset:=0;
- yoffset:=ytabel[y1];
- for i:=0 to height-1 do begin
- x:=midxtabel[i];
- PaintLine(x,@midtabeller[((-x) shl 1)-160]^,yoffset,midytabel[i]);
- inc(yoffset,WIDTH);
- inc(logooffset,320);
- end;
- end;
-
-
- (*------------------------------------------------*)
-
- procedure RunOnce;
- var
- i : integer;
- begin
- SwapDisplay;
- while retraces=0 do ;
- retraces:=0;
- {$IFDEF DEBUG}
- i:=retraces;
- while retraces=i do ;
- SetRGB(0,30,0,0);
- {$ENDIF}
-
- ClearTopBottom;
- CalcVinkel;
- RotateAllCoords;
- DrawFace(cbuffer[1],cbuffer[2],cbuffer[3],cbuffer[4]);
- DrawFace(cbuffer[3],cbuffer[4],cbuffer[5],cbuffer[6]);
- DrawFace(cbuffer[5],cbuffer[6],cbuffer[7],cbuffer[8]);
- DrawFace(cbuffer[7],cbuffer[8],cbuffer[1],cbuffer[2]);
- DrawScreen;
-
- {$IFDEF DEBUG}
- SetRGB(0,0,0,0);
- {$ENDIF}
- end;
-
-
- begin
- OpenScreen;
- Screen_Off;
- InitDemo;
- SetAllInterrupts;
- Screen_On;
- repeat RunOnce until Key='e';
- RestoreAllInterrupts;
- UninitDemo;
- CloseScreen;
- end.
-